package aor2.cpu.blockcontrol;

import aor2.components.Restorable;
import aor2.components.SignalSet;
import aor2.cpu.blockoperation.AlushiftSignal;

/**
 * Skup kontrolnih signala se ne dovode na in ili out komponente ElementIO, i
 * bez operacionih signala Alu jedinice, za sad.!
 * 
 * @author Moxi
 * 
 */

/*
 * VAZNO: prilikom kreiranja Elementa koji koristi neki od ovih signala za
 * signal postaviti source i destination - pogledati konstruktore recimo
 * AlushiftXYM1, i static blok kod npr GPRRegister!
 */
public class ControlSignalSet extends SignalSet implements Restorable {
	private static ControlSignalSet singleton = null;

	private ControlSignalSet() {
		super();

		// registri
		add("REGin");
		add("REGout");
		add("PCin");
		add("PCout");
		add("SPin");
		add("SPout");
		add("opsel");

		// interfejs
		add("mxMAR");
		add("MARin");
		add("MBRin");
		add("M1MBRout");
		add("M2MBRout");

		// reginstrukcija

		add("IR0in");
		add("IR1in");
		add("IR2in");
		add("IR0out");
		add("IR1out");
		add("IR2out");
		add("IR0Lout");

		// ALU
		add("Ain");
		add("Aout");
		add("Bin");
		add("Bout");

		add("ALUSHIFTout");
		add("Xin");
		add("Yin");

		add("PSWin");
		add("PSWout");
		add("ldpsw");
		add("ldpswl");
		add("clpswi");
		add("clpswt");
		add("stpswt");
		add("stpswi");

		add("inc", AlushiftSignal.inc.getSignal());
		add("dec", AlushiftSignal.dec.getSignal());
		add("not", AlushiftSignal.not.getSignal());
		add("asr", AlushiftSignal.asr.getSignal());
		add("shl", AlushiftSignal.shl.getSignal());
		add("trans", AlushiftSignal.trans.getSignal());
		add("sgnext", AlushiftSignal.sgnext.getSignal());
		add("sub", AlushiftSignal.sub.getSignal());
		add("add", AlushiftSignal.add.getSignal());
		add("or", AlushiftSignal.or.getSignal());
		add("nop", AlushiftSignal.nop.getSignal());

		// magistrale
		add("read");
		add("write");

		add("G21");
		add("G12");

		// blok prekid
		add("ldprcod");

		add("stprins");
		add("stpradr");

		add("clprcod");
		add("clpradr");
		add("clprirr");
		add("clprinm");
		add("clprins");

		add("BRUNMSKout");
		add("BRUMSKout");
		add("IVTPout");

		// skokovi;
		// visestruki
		add("brop");
		add("braadr1");
		add("braadr2");
		// signal skoka, nema u parsiranju

		add("branch");
		// bezuslovni
		add("bruncnd");
		// uslovni skokovi
		add("brnotpom1");
		add("brnotpom2");
		add("bradr0");
		add("bradr1");
		add("brregdir2");
		add("brimmed2");
		add("brMOV");
		add("breql");

		add("brnotprekid");
		add("brPRCOD");
		add("brPRADR");
		add("brPRINS");
		add("brPRIMM");
		add("brPRINM");
	}

	public static ControlSignalSet getInstance() {
		if (singleton == null)
			singleton = new ControlSignalSet();
		return singleton;
	}

	@Override
	public void restore(String restorePoint) {
		String trim = restorePoint.replace(beginTag(), "");
		trim = trim.replace(endTag(), "");
		trim = trim.trim();
		String[] states = trim.split(" ");
		int i = 0;

		// brisanje history-a
		get("REGin").clearHistory();
		get("REGout").clearHistory();
		get("PCin").clearHistory();
		get("PCout").clearHistory();
		get("SPin").clearHistory();
		get("SPout").clearHistory();
		get("opsel").clearHistory();

		// interfejs
		get("mxMAR").clearHistory();
		get("MARin").clearHistory();
		get("MBRin").clearHistory();
		get("M1MBRout").clearHistory();
		get("M2MBRout").clearHistory();

		// reginstrukcija

		get("IR0in").clearHistory();
		get("IR1in").clearHistory();
		get("IR2in").clearHistory();
		get("IR0out").clearHistory();
		get("IR1out").clearHistory();
		get("IR2out").clearHistory();
		get("IR0Lout").clearHistory();

		// ALU
		get("Ain").clearHistory();
		get("Aout").clearHistory();
		get("Bin").clearHistory();
		get("Bout").clearHistory();

		get("ALUSHIFTout").clearHistory();
		get("Xin").clearHistory();
		get("Yin").clearHistory();

		get("PSWin").clearHistory();
		get("PSWout").clearHistory();
		get("ldpsw").clearHistory();
		get("ldpswl").clearHistory();
		get("clpswi").clearHistory();
		get("clpswt").clearHistory();
		get("stpswt").clearHistory();
		get("stpswi").clearHistory();

		get("inc").clearHistory();
		get("dec").clearHistory();
		get("not").clearHistory();
		get("asr").clearHistory();
		get("shl").clearHistory();
		get("trans").clearHistory();
		get("sgnext").clearHistory();
		get("sub").clearHistory();
		get("add").clearHistory();
		get("or").clearHistory();
		get("nop").clearHistory();

		// magistrale
		get("read").clearHistory();
		get("write").clearHistory();

		get("G21").clearHistory();
		get("G12").clearHistory();

		// blok prekid
		get("ldprcod").clearHistory();

		get("stprins").clearHistory();
		get("stpradr").clearHistory();

		get("clprcod").clearHistory();
		get("clpradr").clearHistory();
		get("clprirr").clearHistory();
		get("clprinm").clearHistory();
		get("clprins").clearHistory();

		get("BRUNMSKout").clearHistory();
		get("BRUMSKout").clearHistory();
		get("IVTPout").clearHistory();

		// skokovi;
		// visestruki
		get("brop").clearHistory();
		get("braadr1").clearHistory();
		get("braadr2").clearHistory();
		// signal skoka, nema u parsiranju

		get("branch").clearHistory();
		// bezuslovni
		get("bruncnd").clearHistory();
		// uslovni skokovi
		get("brnotpom1").clearHistory();
		get("brnotpom2").clearHistory();
		get("bradr0").clearHistory();
		get("bradr1").clearHistory();
		get("brregdir2").clearHistory();
		get("brimmed2").clearHistory();
		get("brMOV").clearHistory();
		get("breql").clearHistory();

		get("brnotprekid").clearHistory();
		get("brPRCOD").clearHistory();
		get("brPRADR").clearHistory();
		get("brPRINS").clearHistory();
		get("brPRIMM").clearHistory();
		get("brPRINM").clearHistory();

		// nove vrednosti
		get("REGin").setActive(Boolean.parseBoolean(states[i++]));
		get("REGout").setActive(Boolean.parseBoolean(states[i++]));
		get("PCin").setActive(Boolean.parseBoolean(states[i++]));
		get("PCout").setActive(Boolean.parseBoolean(states[i++]));
		get("SPin").setActive(Boolean.parseBoolean(states[i++]));
		get("SPout").setActive(Boolean.parseBoolean(states[i++]));
		get("opsel").setActive(Boolean.parseBoolean(states[i++]));

		// interfejs
		get("mxMAR").setActive(Boolean.parseBoolean(states[i++]));
		get("MARin").setActive(Boolean.parseBoolean(states[i++]));
		get("MBRin").setActive(Boolean.parseBoolean(states[i++]));
		get("M1MBRout").setActive(Boolean.parseBoolean(states[i++]));
		get("M2MBRout").setActive(Boolean.parseBoolean(states[i++]));

		// reginstrukcija

		get("IR0in").setActive(Boolean.parseBoolean(states[i++]));
		get("IR1in").setActive(Boolean.parseBoolean(states[i++]));
		get("IR2in").setActive(Boolean.parseBoolean(states[i++]));
		get("IR0out").setActive(Boolean.parseBoolean(states[i++]));
		get("IR1out").setActive(Boolean.parseBoolean(states[i++]));
		get("IR2out").setActive(Boolean.parseBoolean(states[i++]));
		get("IR0Lout").setActive(Boolean.parseBoolean(states[i++]));

		// ALU
		get("Ain").setActive(Boolean.parseBoolean(states[i++]));
		get("Aout").setActive(Boolean.parseBoolean(states[i++]));
		get("Bin").setActive(Boolean.parseBoolean(states[i++]));
		get("Bout").setActive(Boolean.parseBoolean(states[i++]));

		get("ALUSHIFTout").setActive(Boolean.parseBoolean(states[i++]));
		get("Xin").setActive(Boolean.parseBoolean(states[i++]));
		get("Yin").setActive(Boolean.parseBoolean(states[i++]));

		get("PSWin").setActive(Boolean.parseBoolean(states[i++]));
		get("PSWout").setActive(Boolean.parseBoolean(states[i++]));
		get("ldpsw").setActive(Boolean.parseBoolean(states[i++]));
		get("ldpswl").setActive(Boolean.parseBoolean(states[i++]));
		get("clpswi").setActive(Boolean.parseBoolean(states[i++]));
		get("clpswt").setActive(Boolean.parseBoolean(states[i++]));
		get("stpswt").setActive(Boolean.parseBoolean(states[i++]));
		get("stpswi").setActive(Boolean.parseBoolean(states[i++]));

		get("inc").setActive(Boolean.parseBoolean(states[i++]));
		get("dec").setActive(Boolean.parseBoolean(states[i++]));
		get("not").setActive(Boolean.parseBoolean(states[i++]));
		get("asr").setActive(Boolean.parseBoolean(states[i++]));
		get("shl").setActive(Boolean.parseBoolean(states[i++]));
		get("trans").setActive(Boolean.parseBoolean(states[i++]));
		get("sgnext").setActive(Boolean.parseBoolean(states[i++]));
		get("sub").setActive(Boolean.parseBoolean(states[i++]));
		get("add").setActive(Boolean.parseBoolean(states[i++]));
		get("or").setActive(Boolean.parseBoolean(states[i++]));
		get("nop").setActive(Boolean.parseBoolean(states[i++]));

		// magistrale
		get("read").setActive(Boolean.parseBoolean(states[i++]));
		get("write").setActive(Boolean.parseBoolean(states[i++]));

		get("G21").setActive(Boolean.parseBoolean(states[i++]));
		get("G12").setActive(Boolean.parseBoolean(states[i++]));

		// blok prekid
		get("ldprcod").setActive(Boolean.parseBoolean(states[i++]));

		get("stprins").setActive(Boolean.parseBoolean(states[i++]));
		get("stpradr").setActive(Boolean.parseBoolean(states[i++]));

		get("clprcod").setActive(Boolean.parseBoolean(states[i++]));
		get("clpradr").setActive(Boolean.parseBoolean(states[i++]));
		get("clprirr").setActive(Boolean.parseBoolean(states[i++]));
		get("clprinm").setActive(Boolean.parseBoolean(states[i++]));
		get("clprins").setActive(Boolean.parseBoolean(states[i++]));

		get("BRUNMSKout").setActive(Boolean.parseBoolean(states[i++]));
		get("BRUMSKout").setActive(Boolean.parseBoolean(states[i++]));
		get("IVTPout").setActive(Boolean.parseBoolean(states[i++]));

		// skokovi;
		// visestruki
		get("brop").setActive(Boolean.parseBoolean(states[i++]));
		get("braadr1").setActive(Boolean.parseBoolean(states[i++]));
		get("braadr2").setActive(Boolean.parseBoolean(states[i++]));
		// signal skoka, nema u parsiranju

		get("branch").setActive(Boolean.parseBoolean(states[i++]));
		// bezuslovni
		get("bruncnd").setActive(Boolean.parseBoolean(states[i++]));
		// uslovni skokovi
		get("brnotpom1").setActive(Boolean.parseBoolean(states[i++]));
		get("brnotpom2").setActive(Boolean.parseBoolean(states[i++]));
		get("bradr0").setActive(Boolean.parseBoolean(states[i++]));
		get("bradr1").setActive(Boolean.parseBoolean(states[i++]));
		get("brregdir2").setActive(Boolean.parseBoolean(states[i++]));
		get("brimmed2").setActive(Boolean.parseBoolean(states[i++]));
		get("brMOV").setActive(Boolean.parseBoolean(states[i++]));
		get("breql").setActive(Boolean.parseBoolean(states[i++]));

		get("brnotprekid").setActive(Boolean.parseBoolean(states[i++]));
		get("brPRCOD").setActive(Boolean.parseBoolean(states[i++]));
		get("brPRADR").setActive(Boolean.parseBoolean(states[i++]));
		get("brPRINS").setActive(Boolean.parseBoolean(states[i++]));
		get("brPRIMM").setActive(Boolean.parseBoolean(states[i++]));
		get("brPRINM").setActive(Boolean.parseBoolean(states[i++]));

	}

	@Override
	public String createRestorePoint() {
		return beginTag()
				+ "\n\t"
				+
				// registri
				get("REGin").isActive()
				+ " "
				+ get("REGout").isActive()
				+ " "
				+ get("PCin").isActive()
				+ " "
				+ get("PCout").isActive()
				+ " "
				+ get("SPin").isActive()
				+ " "
				+ get("SPout").isActive()
				+ " "
				+ get("opsel").isActive()
				+ " "
				+

				// interfejs
				get("mxMAR").isActive()
				+ " "
				+ get("MARin").isActive()
				+ " "
				+ get("MBRin").isActive()
				+ " "
				+ get("M1MBRout").isActive()
				+ " "
				+ get("M2MBRout").isActive()
				+ " "
				+

				// reginstrukcija

				get("IR0in").isActive()
				+ " "
				+ get("IR1in").isActive()
				+ " "
				+ get("IR2in").isActive()
				+ " "
				+ get("IR0out").isActive()
				+ " "
				+ get("IR1out").isActive()
				+ " "
				+ get("IR2out").isActive()
				+ " "
				+ get("IR0Lout").isActive()
				+ " "
				+

				// ALU
				get("Ain").isActive() + " " + get("Aout").isActive()
				+ " "
				+ get("Bin").isActive()
				+ " "
				+ get("Bout").isActive()
				+ " "
				+

				get("ALUSHIFTout").isActive()
				+ " "
				+ get("Xin").isActive()
				+ " "
				+ get("Yin").isActive()
				+ " "
				+

				get("PSWin").isActive()
				+ " "
				+ get("PSWout").isActive()
				+ " "
				+ get("ldpsw").isActive()
				+ " "
				+ get("ldpswl").isActive()
				+ " "
				+ get("clpswi").isActive()
				+ " "
				+ get("clpswt").isActive()
				+ " "
				+ get("stpswt").isActive()
				+ " "
				+ get("stpswi").isActive()
				+ " "
				+

				get("inc").isActive()
				+ " "
				+ get("dec").isActive()
				+ " "
				+ get("not").isActive()
				+ " "
				+ get("asr").isActive()
				+ " "
				+ get("shl").isActive()
				+ " "
				+ get("trans").isActive()
				+ " "
				+ get("sgnext").isActive()
				+ " "
				+ get("sub").isActive()
				+ " "
				+ get("add").isActive()
				+ " "
				+ get("or").isActive()
				+ " "
				+ get("nop").isActive()
				+ " "
				+

				// magistrale
				get("read").isActive()
				+ " "
				+ get("write").isActive()
				+ " "
				+

				get("G21").isActive()
				+ " "
				+ get("G12").isActive()
				+ " "
				+

				// blok prekid
				get("ldprcod").isActive()
				+ " "
				+

				get("stprins").isActive()
				+ " "
				+ get("stpradr").isActive()
				+ " "
				+

				get("clprcod").isActive()
				+ " "
				+ get("clpradr").isActive()
				+ " "
				+ get("clprirr").isActive()
				+ " "
				+ get("clprinm").isActive()
				+ " "
				+ get("clprins").isActive()
				+ " "
				+

				get("BRUNMSKout").isActive()
				+ " "
				+ get("BRUMSKout").isActive()
				+ " "
				+ get("IVTPout").isActive()
				+ " "
				+

				// skokovi;
				// visestruki
				get("brop").isActive()
				+ " "
				+ get("braadr1").isActive()
				+ " "
				+ get("braadr2").isActive()
				+ " "
				+
				// signal skoka, nema u parsiranju

				get("branch").isActive()
				+ " "
				+
				// bezuslovni
				get("bruncnd").isActive()
				+ " "
				+
				// uslovni skokovi
				get("brnotpom1").isActive() + " " + get("brnotpom2").isActive()
				+ " " + get("bradr0").isActive() + " "
				+ get("bradr1").isActive() + " " + get("brregdir2").isActive()
				+ " " + get("brimmed2").isActive() + " "
				+ get("brMOV").isActive() + " " + get("breql").isActive() + " "
				+

				get("brnotprekid").isActive() + " " + get("brPRCOD").isActive()
				+ " " + get("brPRADR").isActive() + " "
				+ get("brPRINS").isActive() + " " + get("brPRIMM").isActive()
				+ " " + get("brPRINM").isActive() + " " + "\n" + endTag();
	}

	@Override
	public String beginTag() {
		return "<ControlSignalSet>";
	}

	@Override
	public String endTag() {
		return "</ControlSignalSet>";
	}

	public static void main(String[] args) {
		ControlSignalSet css = ControlSignalSet.getInstance();

		String res = css.createRestorePoint();
		System.out.println(res);

		css.restore(res);

		res = css.createRestorePoint();
		System.out.println(res);

	}
}
